package com.uzai.console.web.reportpanel;

import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.uzai.common.exception.BusinessException;
import com.uzai.console.dto.reportpanel.DataPanelOptDto;
import com.uzai.console.dto.reportpanel.DataPanelQueryDto;
import com.uzai.console.enums.ReportPanelTypeEnum;
import com.uzai.console.service.reportpanel.BaseDataPanelService;
import com.uzai.console.vo.reportpanel.DataPanelVo;
import com.uzai.console.web.BaseController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * 粉丝价值
 *
 * @author liuqi
 * @date 2021年08月16日 15:11
 */
@Api(value = "数据面板控制器", tags = "数据面板")
@ApiSort(50)
@RestController
@Slf4j
public class DataPanelController extends BaseController implements ApplicationContextAware {
    private final Map<Integer, BaseDataPanelService> dataPanelServiceCache = new HashMap<>(8);

    @ApiOperation(value = "分页查询数据面板", notes = "分页查询数据面板", response = DataPanelVo.class)
    @ApiOperationSupport(order = 1)
    @PostMapping("/dataPanel/findByPage")
    public Object findByPage(@RequestBody DataPanelQueryDto panelOptDto) {
        if (Objects.isNull(panelOptDto) || Objects.isNull(panelOptDto.getType())) {
            throw new BusinessException("获取数据面板列表失败: 参数错误");
        }
        BaseDataPanelService baseDataPanelService = dataPanelServiceCache.get(panelOptDto.getType());
        if (Objects.isNull(baseDataPanelService)) {
            throw new BusinessException("获取数据面板列表失败");
        }
        return baseDataPanelService.pageDataPanel(panelOptDto);
    }

    @ApiOperation(value = "根据id数据面板详情", notes = "根据id数据面板详情", response = DataPanelVo.class)
    @ApiOperationSupport(order = 1)
    @PostMapping("/dataPanel/findById")
    public Object findById(@RequestBody DataPanelQueryDto panelOptDto) {
        if (Objects.isNull(panelOptDto) || Objects.isNull(panelOptDto.getId()) || Objects.isNull(panelOptDto.getType())) {
            throw new BusinessException("获取数据面板详情失败: 参数错误");
        }
        BaseDataPanelService baseDataPanelService = dataPanelServiceCache.get(panelOptDto.getType());
        if (Objects.isNull(baseDataPanelService)) {
            throw new BusinessException("获取数据面板详情失败");
        }
        return baseDataPanelService.getDataPanelById(panelOptDto.getId(), panelOptDto.getMerId());
    }

    @ApiOperation(value = "添加数据面板", notes = "添加好友请求报表面板", response = Boolean.class)
    @ApiOperationSupport(order = 2)
    @PostMapping("/dataPanel/add")
    public Object add(@RequestBody DataPanelOptDto panelOptDto) {
        if (Objects.isNull(panelOptDto) || Objects.isNull(panelOptDto.getMerId()) || StringUtils.isBlank(panelOptDto.getDeviceType())
                || ObjectUtils.isEmpty(panelOptDto.getDeviceUniqueIdList()) || Objects.isNull(panelOptDto.getQueryStartTime())
                || ObjectUtils.isEmpty(panelOptDto.getShowFieldList()) || Objects.isNull(panelOptDto.getType())) {
            throw new BusinessException("创建数据面板失败: 参数错误");
        }
        BaseDataPanelService baseDataPanelService = dataPanelServiceCache.get(panelOptDto.getType());
        if (Objects.isNull(baseDataPanelService)) {
            throw new BusinessException("创建数据面板失败");
        }
        baseDataPanelService.addDataPanel(panelOptDto);
        return true;
    }

    @ApiOperation(value = "修改数据面板", notes = "修改数据面板", response = Boolean.class)
    @ApiOperationSupport(order = 2)
    @PostMapping("/dataPanel/edit")
    public Object edit(@RequestBody DataPanelOptDto panelOptDto) {
        if (Objects.isNull(panelOptDto) || Objects.isNull(panelOptDto.getId()) || Objects.isNull(panelOptDto.getType())) {
            throw new BusinessException("修改数据面板失败: 参数错误");
        }
        BaseDataPanelService baseDataPanelService = dataPanelServiceCache.get(panelOptDto.getType());
        if (Objects.isNull(baseDataPanelService)) {
            throw new BusinessException("修改数据面板失败");
        }
        baseDataPanelService.editDataPanel(panelOptDto);
        return true;
    }

    @ApiOperation(value = "删除数据面板", notes = "删除数据面板", response = Boolean.class)
    @ApiOperationSupport(order = 3)
    @PostMapping("/dataPanel/deleteById")
    public Object deleteById(@RequestBody DataPanelOptDto panelOptDto) {
        if (Objects.isNull(panelOptDto) || Objects.isNull(panelOptDto.getMerId()) || Objects.isNull(panelOptDto.getId()) || Objects.isNull(panelOptDto.getType())) {
            throw new BusinessException("删除数据面板失败: 参数错误");
        }
        BaseDataPanelService baseDataPanelService = dataPanelServiceCache.get(panelOptDto.getType());
        if (Objects.isNull(baseDataPanelService)) {
            throw new BusinessException("删除数据面板失败");
        }
        baseDataPanelService.deleteDataPanel(panelOptDto);
        return true;
    }

    @ApiOperation(value = "获取数据面板显示字段列表", notes = "获取数据面板显示字段列表", response = HashMap.class)
    @ApiOperationSupport(order = 4)
    @PostMapping("/dataPanel/showFieldList")
    public Object showFieldList(@RequestBody DataPanelQueryDto queryDto) {
        if (Objects.isNull(queryDto) || Objects.isNull(queryDto.getType())) {
            throw new BusinessException("数据面板显示字段获取失败: 参数错误");
        }
        BaseDataPanelService baseDataPanelService = dataPanelServiceCache.get(queryDto.getType());
        if (Objects.isNull(baseDataPanelService)) {
            throw new BusinessException("数据面板显示字段获取失败");
        }
        return baseDataPanelService.showFieldList();
    }

    @ApiOperation(value = "数据面板备注", notes = "数据面板备注", response = Boolean.class)
    @ApiOperationSupport(order = 5)
    @PostMapping("/dataPanel/remark")
    public Object remark(@RequestBody DataPanelOptDto optDto) {
        if (Objects.isNull(optDto) || ObjectUtils.anyNull(optDto.getType(), optDto.getId()) || StringUtils.isBlank(optDto.getRemark())) {
            throw new BusinessException("数据面板备注参数错误");
        }
        BaseDataPanelService baseDataPanelService = dataPanelServiceCache.get(optDto.getType());
        if (Objects.isNull(baseDataPanelService)) {
            throw new BusinessException("数据面板备注获取失败");
        }
        return baseDataPanelService.remark(optDto.getId(), optDto.getRemark());
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        // 获取到所有的数据面板业务方法
        Map<String, BaseDataPanelService> beansOfType = applicationContext.getBeansOfType(BaseDataPanelService.class);

        if (ObjectUtils.isEmpty(beansOfType)) {
            return;
        }

        for (BaseDataPanelService baseDataPanelService : beansOfType.values()) {
            ReportPanelTypeEnum dataPanelType = baseDataPanelService.getDataPanelType();

            if (dataPanelServiceCache.containsKey(dataPanelType.getId())) {
                throw new IllegalStateException("数据面板类型重复,请检查代码");
            }
            dataPanelServiceCache.put(dataPanelType.getId(), baseDataPanelService);
        }
    }
}
